/**********************************************************************
 *   Copyright: (C)2024 LingYun IoT System Studio
 *      Author: LiJiahui<2199250859@qq.com>
 *
 * Description: The purpose of this code is to provide a simple C library,
 *              which providing software bit-bang of the I2C protocol on
 *              any GPIO pins for ISKBoard.
 *
 *   ChangeLog:
 *        Version    Date       Author            Description
 *        V1.0.0  2024.08.29    LiJiahui      Release initial version
 *
 ***********************************************************************/

#ifndef __I2C_BITBANG_H_
#define __I2C_BITBANG_H_


#include "stm32l4xx_hal.h"

#define I2C_CLK_STRETCH_TIMEOUT	6000

typedef enum i2c_num_e
{
	I2CBUS0,
	I2CBUS1,
	I2CBUSMAX,
}i2c_num_t;

/* I2C GPIO port Level functions */

/* GPIO port for I2C typedef */
typedef struct i2c_gpio_s
{
	GPIO_TypeDef	*group;
	uint16_t		pin;
}i2c_gpio_t;

/* I2C bus typedef */
typedef struct i2c_bus_s
{
	uint8_t			bus;  /* Bus number */
	uint8_t			addr; /* 7-bits slave address */
	i2c_gpio_t		scl;  /* SCL GPIO pin */
	i2c_gpio_t		sda;  /* SDA GPIO pin */
}i2c_bus_t;


/* I2C High level API functions */

/* I2C bus error number */
enum
{
	ERROR_NONE		= 0X00, //no error
	ERROR_PARM		= 0X01, //parameter out of range error
	ERROR_ACK		= 0X02, //no acknowledge error
	ERROR_TIMEOUT	= 0X03, //timeout error
	ERROR_CHECKSUM	= 0X04, //checksum mismatch error
	PARM_ERROR     = 0x80, // parameter out of range error
};

/* Set I2C slave device 7-bits address in the bus to lock it */
//extern int i2c_lock(uint8_t addr);

/* Clear I2C slave device 7-bits address in the bus to free it */
//extern void i2c_free(void);

/* write data by to slave device */
extern int i2c_write(uint8_t bus, uint8_t *data, int bytes);

extern int i2c_lock(uint8_t bus, uint8_t addr);

/* read data from slave device */
extern int i2c_read(uint8_t bus, uint8_t *buf, int size);

extern int i2c_init(uint8_t bus, uint8_t addr);

extern int i2c_term(uint8_t bus);

/* I2C Low level API functions */

/* Send I2C start condition */
extern void I2C_StartCondition(uint8_t bus);

/* Send I2C stop condition */
extern void I2C_StopCondition(uint8_t bus);

/* send I2C slave device 8-bits address */
#define W_ADDR(x)	((x)<<1) 		/* I2C address bit[0]=0 means write */
#define R_ADDR(x)	((x)<<1 | 1)	/* I2C address bit[0]=1 means read  */
enum
{
	I2C_WR, //Write
	I2C_RD, //Read
};
extern int I2C_SendAddress(uint8_t bus, uint8_t dir);

extern int I2C_WriteByte(uint8_t bus, uint8_t txByte);

/* Read a byte data from I2C slave device */
enum
{
	ACK_NONE,
	ACK,
	NAK,
};
extern int I2C_ReadByte(uint8_t bus, uint8_t *rxByte, uint8_t ack, uint32_t timeout);

#endif
